你相信嗎?大量 UI 本身,就可能成為 Runtime Cost
前幾天,我們一直在追 資料發生變化之後,Vue 到底需要做多少工作?
Reactive Chain Hell 看的是一次資料變更,Reactive Graph 會把更新傳到哪裡?
Component Storm 接著看一次更新,會影響多少 Component?
到了大量列表,問題開始換一個方向。
假設 API 一次拿回 5,000 筆商品,資料已經存在 JavaScript 裡,接下來的問題是 這 5,000 筆資料要變成畫面,瀏覽器需要做多少工作?
從 JavaScript 的角度來看,5,000 筆商品可能只是一個 Array:
API
│
▼
5,000 items
但如果這些資料全部需要出現在畫面上,事情就會繼續往下發生:
5,000 items
│
▼
建立 UI
│
▼
大量 DOM
│
▼
Style / Layout
│
▼
Paint / Composite
│
▼
畫面呈現
而且一個商品通常也不會只有一個 <div> ,可能還包含:
Product Card
├─ Image
├─ Title
├─ Price
├─ Badge
├─ Rating
└─ Button
因此真正需要處理的 UI 數量,往往會比 5,000 筆資料這個數字更大,這也是大型列表常見的問題 資料量增加之後,UI Workload 也跟著增加。

裝置效能確實會影響執行時間,假設同樣需要處理 5,000 個 UI:
較慢裝置
5,000 UI
↓
需要較長時間完成
較快裝置
5,000 UI
↓
需要較短時間完成
更快的 CPU、GPU 或瀏覽器環境,可以讓這些工作更快完成,但是有一個問題仍然存在:
裝置變快
↓
單位工作時間下降
UI 數量不變
↓
總工作量仍然存在
所以當列表從 100 筆增加到 5,000 筆時,值得追蹤的問題就不只是「裝置夠不夠快」,還需要知道 UI 數量增加之後,究竟增加了哪些工作?
如果直接拿大型電商網站測試,很容易得到一個真的很慢的結果,但我們很難知道慢在哪裡,因為一個真實列表可能同時包含:
API / Network
│
▼
State Management
│
▼
Vue Reactivity
│
▼
Component Tree
│
▼
DOM
│
▼
CSS / Layout / Paint
最後看到一個 500ms 的結果時,還會有很多問題:
如果這些因素全部混在一起,就很難回答我們真正想研究的問題。
Day 16 想研究的事情其實只是 UI 數量持續增加,瀏覽器需要付出多少成本?
因此下一個 Scenario 會刻意移除與這個問題無關的因素:
VDOM Stress Test
UI 數量增加
│
▼
┌─────────────────┐
│ Vue 建立 UI │
└────────┬────────┘
│
▼
大量 DOM
│
┌──────────┼──────────┐
▼ ▼ ▼
Scripting Rendering Painting
這裡不需要 API、Pinia、Router,也不需要複雜的商業邏輯,只需要控制一個重要變數:
UI Count
100
↓
500
↓
1,000
↓
5,000
然後觀察成本如何隨著 UI 數量增加而變化。
因此 Scenario 本身會非常簡單,概念上只需要建立大量相同結構的 UI,商品內容不重要,真正重要的是 <div> 數量逐步增加,建立這些 UI 的成本如何變化?
<div
v-for="item in items"
:key="item.id"
class="card"
>
<h3>{{ item.title }}</h3>
<p>{{ item.price }}</p>
<button>Buy</button>
</div>
這也是為什麼這個 Scenario 叫做 VDOM Stress Test。
它關注的不是 VDOM 本身的理論,而是當 Vue 需要處理大量 UI 時,整個 Rendering Workload 會發生什麼變化。
如果最後只得到 5,000 個 UI 比 500 個 UI 慢,這個結果其實不夠有價值。
因為「慢」只是一個現象,我們還需要知道時間主要落在哪裡,所以可以先用 Browser Performance 的工作類型來理解:
Browser Work
│
├─ Scripting
│ └─ JavaScript / Vue Runtime
│
├─ Rendering
│ ├─ Style
│ └─ Layout
│
└─ Painting
└─ Paint / Composite
因此後續驗證會關注幾個方向:
| 指標 | 想回答的問題 |
|---|---|
| Execution / Duration | 整體工作花多久? |
| Scripting | JavaScript 與 Vue 相關工作增加多少? |
| Rendering | Style / Layout 成本是否增加? |
| Painting | Paint 成本是否增加? |
| FPS | UI 增加後是否開始影響畫面更新? |
| Memory | 大量 UI 是否帶來額外記憶體壓力? |
這些指標的目的是運用 DevTools 數字回答一個核心問題:
大量 UI 帶來的成本,主要落在哪一層?
做到這裡,前面的三個 Scenario 可以放在同一張圖裡看。
Vue UI Performance
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Reactive Chain Component Storm VDOM Stress
│ │ │
▼ ▼ ▼
更新傳播到哪裡? 影響多少 Component? 需要處理多少 UI?
│ │ │
▼ ▼ ▼
Reactive Graph Component Tree Rendering
它們可能在同一次操作中同時出現,但每個 Scenario 都刻意放大一個不同的維度:
| Scenario | 核心問題 | 主要觀察 |
|---|---|---|
| Reactive Chain Hell | 更新會傳到哪裡? | Reactive Graph |
| Component Storm | 更新會經過多少 Component? | Component Tree |
| VDOM Stress Test | UI 數量增加後會發生什麼? | Rendering Workload |
這樣看,大量列表的問題就會更清楚,當資料很多時,問題不一定停留在「資料有多少」。
資料一旦需要轉成大量 UI,就會進一步產生:
Data
↓
UI Instances
↓
DOM
↓
Browser Work
而我們真正需要驗證的,是這條路徑上的成本如何隨著 UI 數量增加。
Day 16 先把問題縮小到「大量 UI」本身。
下一篇會正式建立 VDOM Stress Test,固定 Scenario 結構,只改變 UI 數量,從:
N = 100
N = 500
N = 1,000
N = 5,000
開始建立 baseline。
接著再比較不同 Vue 版本的結果。
這一次要回答的問題也很明確:
當 UI 數量從 100 增加到 5,000,成本增加在哪裡?Vue Runtime 又佔了多少?
等 baseline 跑完,才有資格進一步討論 Vue 3.6 是否真的改善了這類大量 UI 的成本。